#include "ThreadCach.h"

void* ThreadCach::Allocate(size_t size) {
    assert(size > 0);
    size_t AlignSize = SizeMapClass::RoundUp(size);//计算对齐后的大小
    size_t index = SizeMapClass::Index(size);//计算对齐后的哈希桶下标
    if (!freeList_[index].Empty()) {
        return freeList_[index].Pop();
    }
    else {
        return ToCentralCache(index, AlignSize); //去中心缓存分配
    }
}

void* ThreadCach::ToCentralCache(const size_t& index, const size_t& AlignSize) {
    //满增长反馈调节算法
    size_t batchNum = std::min(freeList_[index].MaxSize(), SizeMapClass::NumMoveSize(AlignSize));
    if (batchNum == freeList_[index].MaxSize()) {
        freeList_[index].MaxSize() += 1;
    }

    void* start = nullptr;//输出型参数
    void* end = nullptr;//输出型参数
    size_t actualNum = CentralCach::GetInstance()->FenchRangeObj(start, end, batchNum, AlignSize);//中心缓存分配
    assert(actualNum > 0);//实际个数得大于0
    if (actualNum == 1) {
        assert(start == end);
        return start;
    }
    else {
        freeList_[index].PushRange(NextPtr(start), end, actualNum - 1);//多余的放入free链表
        return start;
    }
}


void ThreadCach::DeAllocate(void* ptr, size_t size) {
    assert(ptr);
    assert(size <= MAXBYTES);
    size_t index = SizeMapClass::Index(size);
    freeList_[index].Push(ptr);

    //当链表长度大于一次 批量向CenetralCach 获取的长度时, 归还一些空间给CentalCach
    if (freeList_[index].Size() >= freeList_[index].MaxSize()) {
        ListTooLong(freeList_[index], size);
    }
}

//freelist空闲内存块太多,还给CentralCach一些
void ThreadCach::ListTooLong(FreeList& list, size_t size) {
    void* start = nullptr;
    void* end = nullptr;
    list.PopRange(start, end, list.MaxSize());//start end输出型参数,从freelist弹出一段内存块链表

    CentralCach::GetInstance()->ReleaseListToCentralCach(start, size);//交给CentralCach
}


